package com.tanhua.admin.service;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.tanhua.admin.exception.BusinessException;
import com.tanhua.admin.mapper.AnalysisMapper;
import com.tanhua.admin.mapper.LogMapper;
import com.tanhua.model.pojo.Analysis;
import com.tanhua.model.vo.AnalysisSummaryVo;
import com.tanhua.model.vo.CountVo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;
import java.util.concurrent.TimeUnit;

//统计数据的类
@Service
public class AnalysisService {

    @Resource
    private LogMapper logMapper;

    @Resource
    private AnalysisMapper analysisMapper;

    //日期的格式
    private final String dateFormat = "yyyy-MM-dd";


    private final String voDateFormat = "MM月dd日";




    //统计当天的用户使用数据
    public void analysis() {
        //1 获取今天和昨天的日期  yyyy-MM-dd
        String today = DateUtil.format(new Date(), dateFormat);
        String yesterday = DateUtil.yesterday().toString(dateFormat);

        //获取上个星期=========================================================================================
        /*String lastWeek = DateUtil.lastWeek().toString(dateFormat);*/
        //获取上个月的月份=========================================================================================
        /*String lastMonth = DateUtil.lastMonth().toString(dateFormat);*/


        DateTime todayDate = DateUtil.parse(today,dateFormat);//==========================

        //2 实现数据统计的查询
        //新注册用户数
        Integer numRegistered = logMapper.findCountByLogTimeAndType(today, "0102");
        //登陆次数
        Integer numLogin = logMapper.findCountByLogTimeAndType(today, "0101");

        //活跃用户数
        Integer numActive = logMapper.findNumActive(today);



        //次日留存用户数
        Integer numRetention1d = logMapper.findNumRetention1d(today, yesterday);

        //3 查询当天统计的数据对象
        Analysis analysis = analysisMapper.selectOne(Wrappers.lambdaQuery(Analysis.class)
                .eq(Analysis::getRecordDate, todayDate));

        //4 判断当天的统计数据是否存在
        if (analysis == null) {
            // 如果不存在就新增
            analysis = new Analysis();
            analysis.setRecordDate(todayDate);
            analysis.setNumRegistered(numRegistered);
            analysis.setNumLogin(numLogin);
            analysis.setNumActive(numActive);
            analysis.setNumRetention1d(numRetention1d);

            analysisMapper.insert(analysis);
        } else {
            // 如果存在就进行修改
            analysis.setNumRegistered(numRegistered);
            analysis.setNumLogin(numLogin);
            analysis.setNumActive(numActive);
            analysis.setNumRetention1d(numRetention1d);

            analysisMapper.updateById(analysis);
        }

    }

    //概要统计信息
    public AnalysisSummaryVo getSummary() {
        //1 创建vo对象
        AnalysisSummaryVo vo = new AnalysisSummaryVo();

        //2 查询今天的和昨天的统计数据
        String today = DateUtil.format(new Date(), dateFormat);
        String yesterday = DateUtil.yesterday().toString(dateFormat);


        //获取上个月的月份===========================================================================================
        String lastmonth = DateUtil.lastMonth().toString(dateFormat);

        //获取上个月份的天数
        /*String date=lastmonth;
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM");
        Calendar calendar =Calendar.getInstance();
        try {
            calendar.setTime(dateFormat.parse(date));
        }catch (Exception e){
            throw new RuntimeException(e);
        }

        calendar.set(Calendar.MONTH, calendar.get(Calendar.MONTH));
        calendar.set(Calendar.DATE, 1);
        calendar.roll(Calendar.DATE,-1);
        int time1 =calendar.get(Calendar.DATE);
        System.out.println(time1);*/

        //查询一个星期之前的统计数据=========================================================================================
        String lastweek = DateUtil.lastWeek().toString(dateFormat);

        Date lastweekDate = DateUtil.parse(lastweek, dateFormat);//=============================
        DateTime lastmonthDate = DateUtil.parse(lastmonth, dateFormat);

        Date todayDate = DateUtil.parse(today, dateFormat);

        Date yesterdayDate = DateUtil.parse(yesterday, dateFormat);


        //过去7天活跃用户数=====================================================================================
        /*获取七天前的日期*/
        Long oneWeek = todayDate.getTime()-7*24*60*60*1000;
        DateTime oneWeekAgo = DateTime.of(oneWeek);


        Long passWeek = analysisMapper.activePass(DateUtil.format(todayDate,dateFormat),DateUtil.format(oneWeekAgo,dateFormat));

        //过去一个月活跃用户=====================================================================================
        Long oneMonth = todayDate.getTime()-30*24*60*60*1000;
        DateTime oneMonthAgo = DateTime.of(oneWeek);
        Long passMonth = analysisMapper.activePass(DateUtil.format(todayDate,dateFormat),DateUtil.format(oneMonthAgo,dateFormat));




        Analysis todayAnalysis = analysisMapper.selectOne(Wrappers.lambdaQuery(Analysis.class)
                .eq(Analysis::getRecordDate, todayDate));

        Analysis yesterdayAnalysis = analysisMapper.selectOne(Wrappers.lambdaQuery(Analysis.class)
                .eq(Analysis::getRecordDate, yesterdayDate));

        Analysis lastweekAnalysis = analysisMapper.selectOne(Wrappers.lambdaQuery(Analysis.class)//=====================
                .eq(Analysis::getRecordDate, lastweekDate));

        Analysis lastmonthAnalysis = analysisMapper.selectOne(Wrappers.lambdaQuery(Analysis.class)//=====================
                .eq(Analysis::getRecordDate, lastmonthDate));


        //3 设置数据到vo中
        //累计用户数 cumulativeUsers  所有的注册用户数之和
        vo.setCumulativeUsers(analysisMapper.cumulativeUsers());

        //今日新增用户数量 newUsersToday
        if(todayAnalysis.getNumRegistered() != null){
            vo.setNewUsersToday(Long.valueOf(todayAnalysis.getNumRegistered()));
        }else{
            vo.setNewUsersToday(0L);
        }
        //今日新增用户涨跌率，单位百分数，正数为涨，负数为跌 newUsersTodayRate
        vo.setNewUsersTodayRate(rate(
                todayAnalysis.getNumRegistered(), yesterdayAnalysis.getNumRegistered())
        );

        //今日登录次数 loginTimesToday
        vo.setLoginTimesToday(Long.valueOf(todayAnalysis.getNumLogin()));

        //一个星期活跃用户==============================================================================
        vo.setActivePassWeek(passWeek);

        //一个月活跃用户
        vo.setActivePassMonth(passMonth);

        //今日登录次数涨跌率，单位百分数，正数为涨，负数为跌 loginTimesTodayRate
        vo.setLoginTimesTodayRate(rate(
                todayAnalysis.getNumLogin(), yesterdayAnalysis.getNumLogin()
        ));

        //今日活跃用户数量 activeUsersToday
        vo.setActiveUsersToday(Long.valueOf(todayAnalysis.getNumActive()));
        //今日活跃用户涨跌率，单位百分数，正数为涨，负数为跌 activeUsersTodayRate
        vo.setActiveUsersTodayRate(rate(
                todayAnalysis.getNumActive(), yesterdayAnalysis.getNumActive()
        ));

        //4 返回结果 vo
        return vo;

    }

    //根据今日的数据和昨日的数据，计算涨跌率
    private Integer rate(int today, int yesterday) {
        int result = 0;

        if (yesterday == 0) {
            //如果前一天的数据量为0   今天没多一个用户的操作，增长率就增加100
            result = today * 100;
        } else {
            result = (today - yesterday) * 100 / yesterday;
        }
        return result;
    }



    /*analysisService.findData(sd, ed, type)*/
    public CountVo findData(Long sd, Long ed, String type) {

        CountVo vo = new CountVo();
        List<Map> thisYear  = new ArrayList<>();
        List<Map> lastYear  = new ArrayList<>();
        DateTime sdDateTime = DateTime.of(sd);  //开始时间
        DateTime edDateTime = DateTime.of(ed);  //结束时间
//        String format1 = DateUtil.format(sdDateTime, dateFormat);
        Long between = DateUtil.between(sdDateTime, edDateTime, DateUnit.DAY);  //两个时间相差的天数
        /*获取一年前的时间*/
        DateTime oneYearAgo = DateUtil.offset(sdDateTime, DateField.MONTH, -12);
//        String OneYearAgeformat = DateUtil.format(oneYearAgo, dateFormat);
        /*101 新增 102 活跃用户 103 次日留存率*/
        if("101".equals(type)){
            for (Integer i = 0; i <= between.intValue(); i++) {
                String format2 = DateUtil.format(DateUtil.offsetDay(sdDateTime,i),dateFormat);   //今年
                Long aLong = analysisMapper.registerPass(format2);
                if(aLong == null){
                    aLong = 0L;
                }
                Map map = new HashMap();
                map.put("title",DateUtil.format(DateUtil.offsetDay(sdDateTime,i),voDateFormat));
                map.put("amount",aLong.intValue());
                thisYear.add(map);

                String format3 = DateUtil.format(DateUtil.offsetDay(oneYearAgo,i),dateFormat);   //去年
                Long aLong1 = analysisMapper.registerPass(format3);  // 新增用户数量
                if(aLong1 == null){
                    aLong1 = 0L;
                }
                map = new HashMap();
                map.put("title",DateUtil.format(DateUtil.offsetDay(oneYearAgo,i),voDateFormat));
                map.put("amount",aLong1);
                lastYear.add(map);
            }
            vo.setThisYear(thisYear);
            vo.setLastYear(lastYear);
        }else if("102".equals(type)){
            for (Integer i = 0; i <= between.intValue(); i++) {
                String format2 = DateUtil.format(DateUtil.offsetDay(sdDateTime,i),dateFormat);   //今年
                Integer aLong = analysisMapper.thisDayActivePass(format2);
                if(aLong == null){
                    aLong = 0;
                }
                Map map = new HashMap();
                map.put("title",DateUtil.format(DateUtil.offsetDay(sdDateTime,i),voDateFormat));
                map.put("amount",aLong.intValue());
                thisYear.add(map);
                String format3 = DateUtil.format(DateUtil.offsetDay(oneYearAgo,i),dateFormat);   //去年
                Integer aLong1 = analysisMapper.thisDayActivePass(format3);  // 新增用户数量
                if(aLong1 == null){
                    aLong1 = 0;
                }
                map = new HashMap();
                map.put("title",DateUtil.format(DateUtil.offsetDay(oneYearAgo,i),voDateFormat));
                map.put("amount",aLong1);
                lastYear.add(map);
            }
            vo.setThisYear(thisYear);
            vo.setLastYear(lastYear);
        }else if("103".equals(type)){
            for (Integer i = 0; i <= between.intValue(); i++) {
                String format2 = DateUtil.format(DateUtil.offsetDay(sdDateTime,i),dateFormat);   //今年

                String yestoday = DateUtil.format(DateUtil.offsetDay(sdDateTime,i-1),dateFormat);  //获取当前时间的前一天
                String beforeYesToday = DateUtil.format(DateUtil.offsetDay(sdDateTime,i-2),dateFormat); //获取前一天


//                Integer aLong = analysisMapper.thisDayActivePass(format2);
                Integer todayRe = logMapper.findNumRetention1d(format2,yestoday);  //次日留存数量
                Integer yesRe = logMapper.findNumRetention1d(yestoday, beforeYesToday);
                if(todayRe == null){
                    todayRe = 0;
                }
                if(yesRe == null){
                    yesRe = 0;
                }

                Map map = new HashMap();
                map.put("title",DateUtil.format(DateUtil.offsetDay(sdDateTime,i),voDateFormat));
                map.put("amount",rate(todayRe,yesRe));
                thisYear.add(map);

                String format3 = DateUtil.format(DateUtil.offsetDay(oneYearAgo,i),dateFormat);   //去年
                String yestodayLast = DateUtil.format(DateUtil.offsetDay(oneYearAgo,i-1),dateFormat);  //获取当前时间的前一天
                String beforeYesTodayLast = DateUtil.format(DateUtil.offsetDay(oneYearAgo,i-2),dateFormat); //获取前一天

                Integer todayReLast = logMapper.findNumRetention1d(format3,yestodayLast);  //次日留存数量
                Integer yesReLast = logMapper.findNumRetention1d(yestodayLast, beforeYesTodayLast);

                if(todayReLast == null){
                    todayReLast = 0;
                }
                if(yesReLast == null){
                    yesReLast = 0;
                }
                map = new HashMap();
                map.put("title",DateUtil.format(DateUtil.offsetDay(oneYearAgo,i),voDateFormat));
                map.put("amount",rate(todayReLast,yesReLast));
                lastYear.add(map);
            }
            vo.setThisYear(thisYear);
            vo.setLastYear(lastYear);
        }else {
            throw new BusinessException("未知异常");
        }


        return vo;
    }
}
